package org.guegan.util.dircompare.bean;

import java.io.File;
import java.util.Date;
import java.util.Set;
import java.util.TreeSet;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name="DIRBEAN")
@NamedQueries({
	@NamedQuery(
			name="DirBean.duplicates",
			query="select p from DirBean p where p.nbFiles > 0 and p.present = 1 order by p.signature, p.name"
	),
	@NamedQuery(
			name="DirBean.nbSubDirs",
			query="select count(p) from DirBean p where p.parent = :parent"
	),
	@NamedQuery(
			name="DirBean.sameName",
			query="select p from DirBean p where p.nbFiles > 0 and p.present = 1 order by p.name, p.signature"
	),
	@NamedQuery(name="DirBean.deleted", query="from DirBean where present = 0 and nbFiles > 0 order by id"),
	@NamedQuery(name="DirBean.loadAll", query="from DirBean order by parent_id")
})
public class DirBean implements Comparable<DirBean> {
	private Long id;

	@Id
    @GeneratedValue(strategy=GenerationType.AUTO)
	public Long getId() {
		return id;
	}
	
	public void setId(Long id) {
		this.id = id;
	}
	
	private String name;
	private Date time;
	private DirBean parent;
	private String signature;
	private int nbFiles;
	private boolean present = true;
	private transient Set<DirBean> subdirs;
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public Date getTime() {
		return time;
	}
	
	public void setTime(Date time) {
		this.time = time;
	}

    @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
	public DirBean getParent() {
		return parent;
	}

	public void setParent(DirBean parent) {
		this.parent = parent;
	}

	public String getSignature() {
		return signature;
	}

	public void setSignature(String signature) {
		this.signature = signature;
	}

	@Transient
	public File getFile() {
		File ret = null;
		File parent = this.parent != null ? this.parent.getFile() : null;
		if (parent != null) {
			ret = new File(parent, name);
		}
		else {
			ret = new File(name);
		}
		return ret;
	}

	private boolean same(String one, String two) {
		boolean ret = one == two;
		if (!ret) {
			ret = (one != null && two != null);
			if (ret) {
				ret = one.equals(two);
			}
		}
		return ret;
	}
	
	public boolean equals(Object other) {
		boolean ret = true;
		ret = other instanceof DirBean; 
		if (ret) {
			DirBean o = (DirBean) other;
			ret = same(o.getSignature(), getSignature());
			if (ret) {
				ret = o.getNbFiles() == getNbFiles();
			}
		}
		return ret;
	}

	public boolean sameNameAndNbFiles(Object other) {
		boolean ret = true;
		ret = other instanceof DirBean; 
		if (ret) {
			DirBean o = (DirBean) other;
			ret = same(o.getName(), getName());
			if (ret) {
				ret = o.getNbFiles() == getNbFiles();
			}
		}
		return ret;
	}

	public int getNbFiles() {
		return nbFiles;
	}

	public void setNbFiles(int nbFiles) {
		this.nbFiles = nbFiles;
	}

	public void setPresent(boolean present) {
		this.present = present;
	}

	public boolean isPresent() {
		return present;
	}
	
	public String toString() {
		String ret = getFile().toString();
		ret += " (" + id + ", " + nbFiles + ")";
		return ret;
	}
	
	@Transient
	public Set<DirBean> getSubdirs() {
		return subdirs;
	}
	
	@Transient
	public void addSubdir(DirBean subdir) {
		if (subdirs == null) {
			subdirs = new TreeSet<DirBean>();
		}
		subdirs.add(subdir);
	}
	
	public int compareTo(DirBean o) {
		int ret = name.compareTo(o.name);
		return ret;
	}
}
